package xsign

import (
	"time"

	"gitee.com/xiaoyutab/xgotool/optional/xcache"
	"gitee.com/xiaoyutab/xgotool/optional/xlog"
	"gitee.com/xiaoyutab/xgotool/xerror"
	"gitee.com/xiaoyutab/xgotool/xstring"
)

// 签到
func Sign(sid, uid, ip, ua uint) error {
	// 批次效验
	sign_info, err := Info(sid)
	if err != nil {
		return err
	}
	if sign_info.Status != 1 {
		return xerror.New("签到批次状态异常")
	}
	if xstring.ToTime(sign_info.StartTime).Unix() > time.Now().Unix() {
		return xerror.New("签到批次暂未开启")
	}
	if xstring.ToTime(sign_info.EndTime).Unix() < time.Now().Unix() {
		return xerror.New("签到批次已结束")
	}
	// 用户效验
	sign_user, err := User(sid, uid)
	if err != nil {
		return err
	}
	switch sign_info.Type {
	case SIGN_ONCE:
		// 总共仅允许签到一次
		if sign_user.PreOnce >= 1 {
			return xerror.New("签到次数已达上限")
		}
	case SIGN_TWICE:
		// 总共仅允许签到两次
		if sign_user.PreOnce >= 2 {
			return xerror.New("签到次数已达上限")
		}
	case SIGN_WORK:
		// 每天签到次数仅允许签到两次
		if sign_user.PreTwce >= 2 {
			return xerror.New("今天的签到次数已达上限")
		}
	default:
		// 单次签到
		if sign_user.PreDate == time.Now().Format(time.DateOnly) {
			return xerror.New("您今天已经签过到了")
		}
	}
	return sign_create(sid, uid, ip, ua)
}

// 创建签到详情
func sign_create(sid, uid, ip, ua uint) error {
	s := SignHistory{
		Sid:       sid,
		Uid:       uid,
		Ip:        ip,
		Ua:        ua,
		CreatedAt: time.Now().Format(time.DateTime),
	}
	// 进行存储
	err := _default.DB.Table(_default.HistoryTable).Create(&s).Error
	if err != nil {
		return xlog.AE("签到详情存储失败", err)
	}
	// 用户签到详情修改
	sign_user, err := User(sid, uid)
	if err != nil {
		return err
	}
	if sign_user.PreDate == time.Now().Format(time.DateOnly) || xstring.ToTime(sign_user.PreDate).AddDate(0, 0, 1).Format(time.DateOnly) == time.Now().Format(time.DateOnly) {
		sign_user.PreTwce++
	} else {
		sign_user.PreTwce = 1
	}
	sign_user.PreDate = time.Now().Format(time.DateOnly)
	sign_user.PreOnce++
	// 回写数据库
	err = _default.DB.Table(_default.SignUserTable).Save(sign_user).Error
	if err != nil {
		return xlog.AE("用户签到详情回写失败", err)
	}
	xcache.SetStruct(xcache.Key("xsign.user", sid, uid), sign_user)
	// 回调通知
	if _default.SignFunc != nil {
		go _default.SignFunc(sign_user)
	}
	return nil
}
